﻿/// <reference path="lib/backbone.js" />

/// <reference path="lib/underscore.js" />

/// <reference path="lib/backbone.localStorage.js" />

/// <reference path="lib/backbone.marionette.js" />

/// <reference path="lib/jquery-1.9.1.min.js" />

/// <reference path="lib/jquery.js" />

/// <reference path="app.js" />

TodoMVC.module('Layouts', function (Layouts, App, Backbone, Marionette, $, _) {


    // Layout Header View
    // ------------------
    Layouts.Header = Marionette.Layout.extend({

        template: '#template-header',

        ui: {
            input: '#new-todo'
        },

        events: {
            'keypress #new-todo': 'onInputKeypress'
        },

        onInputKeypress: function (e) {
            var ENTER_KEY = 13;
            var todoText = this.ui.input.val().trim();

            if (e.whitch === ENTER_KEY && todoText) {
                this.collection.create({ title: todoText });
                this.ui.input.val('');
            }
        }

    });

    // Layout Footer View
    // ------------------

    Layouts.Footer = Marionette.Layout.extend({

        template: '#template-footer',

        ui: {
            count: '#todo-count strong',
            filters: '#filters a'
        },

        events: {
            'click #clear-completed': 'onClearClick'
        },

        initialize: function () {
            this.listenTo(App.vent, 'todoList:filter', this.updateFilterSelection);
            this.listenTo(this.collection, 'all', this.updateCount);
        },

        onRender: function () {
            this.updateCount();
        },

        updateCount: function () {
            var count = this.collection.getActive().length;

            this.ui.count.html(count);

            if (count === 0) {
                this.$el.parent().hide();
            } else {
                this.$el.parent().show();
            }
        },

        updateFilterSelection: function (filter) {
            this.ui.filters
            .removeClass('selected')
            .filter('[href="#' + filter + '"]')
            .addClass('selected');
        },

        onClearClick: function () {
            var completed = this.collection.getCompleted();
            completed.forEach(function (todo) { todo.destroy(); });
        }

    });

});

//TodoMVC.TodoList.js
//--------------------

TodoMVC.module("TodoList", function (TodoList, App, Backbone, Marionette, $, _) {

    // TodoList Router
    // ---------------
    //
    // Handle routes to show the active vs complete todo items

    TodoList.Router = Marionette.AppRouter.extend({
        appRoutes: {
            '*filter': 'filterItems'
        }
    });


    // TodoList Controller (Mediator)
    // ------------------------------
    //
    // Control the workflow and logic that exists at the application

    TodoList.Controller = function () { this.todoList = new App.Todos.TodoList(); }

    _.extend(TodoList.Controller.prototype, {

        // Start the app by showing the appropriate views
        // and fetching the list of todo items, if there are any
        start: function () {
            this.showHeader(this.todoList);
            this.showFooter(this.todoList);
            this.showTodoList(this.todoList);

            this.todoList.fetch();
        },

        showHeader: function (todoList) {
            var header = new App.Layouts.Header({ collection: todoList });
            App.header.show(header);
        },

        showFooter: function (todoList) {
            var footer = new App.Layouts.Footer({ collection: todoList });
            App.footer.show(footer);
        },

        showTodoList: function (todoList) {
            App.main.show(new TodoList.Views.ListView({ collection: todoList }));
        },

        filterItems: function (filter) {
            var f = filter || '';
            App.vent.trigger('todoList:filter', f.trim());
        }
    });

    // TodoList Initializer
    // --------------------
    //
    // Get the TodoList up and running by initializing the mediator
    // when the the application is started, pulling in all of the
    // existing Todo items and displaying them.

    TodoList.addInitializer(function () {

        var controler = new TodoList.Controller();
        new TodoList.Router({
            controller: controler
        });

        controler.start();

    });
});

//
// TodoMVC.TodoList.Views.js
//

TodoMVC.module('TodoList.Views', function (Views, App, Backbone, Marionette, $, _) {

    // Todo List Item View
    // -------------------
    //
    // Display an individual todo item, and respond to changes
    // that are made to the item, including marking completed.

    Views.ItemView = Marionette.ItemView.extend({

        tagName: 'li',

        template: '#template-todoItemView',

        ui: {
            edit: '.edit'
        },

        events: {
            'click .destroy': 'destroy',
            'dbclick label': 'onEditClick',
            'keypress .edit': 'onEditKeypress',
            'click .toggle': 'toggle'
        },
        initialize: function () {
            this.listenTo(this.model, 'change', this.render);
        },
        onRender: function () {
            this.$el.removeClass('active completed');
            if (this.model.get('completed'))
                this.$el.addClass('completed');
            else this.$el.addClass('active');
        },
        destroy: function () {
            this.model.destroy();
        },
        toggle: function () {
            this.model.toggle();
        },
        onEditClick: function () {
            this.$el.addClass('editing');
            this.ui.edit.focus();
        },
        onEditKeypress: function (e) {
            var ENTER_KEY = 13;
            var todoText = this.ui.edit.val().trim();

            if (evt.which === ENTER_KEY && todoText) {
                this.model.set('title', todoText).save();
                this.$el.removeClass('editing');
            }
        }
    });

    // Item List View
    // --------------
    //
    // Controls the rendering of the list of items, including the
    // filtering of active vs completed items for display.

    Views.ListView = Marionette.CompositeView.extend({
        template: '#template-todoListCompositeView',
        itemView: Views.ItemView,
        itemViewContainer: '#todo-list',

        ui: { toggle: '#toggle-all' },

        events: {
            'click #toggle-all': 'onToggleAllClick'
        },

        initialize: function () {

            this.listenTo(this.collection, 'all', this.update);

        },

        onRender: function () {
            this.update();
        },
        update: function () {
            function reduceCompleted(left, right) { return left && right.get('completed'); }

            var allCompleted = this.collection.reduce(reduceCompleted, true);

            this.ui.toggle.prop('checked', allCompleted);

            if (this.collection.length === 0) {
                this.$el.parent().hide();
            } else {
                this.$el.parent().show();
            }
        },
        onToggleAllClick: function (e) {
            var isChecked = e.currentTarget.checked;
            this.collection.each(function (todo) {
                todo.save({ 'completed': isChecked });
            });
        }
    });

    // Application Event Handlers
    // --------------------------
    //
    // Handler for filtering the list of items by showing and
    // hiding through the use of various CSS classes
    App.vent.on('todoList:filter', function (filter) {
        filter = filter || 'all';
        $('#todoapp').attr('class', 'filter-' + filter);
    });

});

//
//Todos.js:
//
TodoMVC.module('Todos', function (Todos, App, Backbone, Marionette, $, _) {
    //todo model
    //
    Todos.Todo = Backbone.Model.extend({
        localStorage: new Backbone.LocalStorage('todos-backbone'),
        default: {
            title: '',
            completed: false,
            created: 0
        },
        initialize: function () {
            if (this.isNew())
                this.set('created',Date.now());
        },
        toggle: function () {
            return this.set('completed', !this.isCompleted);
        },
        isCompleted: function () {
            return this.get('completed');
        }
    });

    // Todo Collection
    // ---------------
    Todos.TodoList = Backbone.Collection.extend({
        model: Todos.Todo,
        localStorage: new Backbone.LocalStorage('todos-backbone'),
        getCompleted: function () {
            return this.filter(this._isCompleted);
        },
        getActive: function() {
            return this.reject(this._isCompleted);
        },
        comparator: function (todo) {
            return todo.get('created');
        },
        _isCompleted: function (todo) {
            return todo.isCompleted();
        }
    });
});

$(function () {
    // Start the TodoMVC app (defined in js/TodoMVC.js)
    TodoMVC.start();
});